MOOC Utils

Utils like auto assignment solver extension and course notice announcment notification for MOOC courses

API schemas

Introduction#

Pydantic request and response schemas for the Notice Reminders API:

  • User operations
  • Course search and management
  • Announcement retrieval and filtering
  • Subscription CRUD
  • Notification delivery and status
  • Authentication flows

Project structure#

The API is organized around routers and schemas. The application factory registers routers and sets up CORS and database initialization. Schemas define request/response contracts, while Tortoise ORM models define persistence.

Core components#

This section summarizes the primary Pydantic models grouped by functional area. Each model’s role, validation rules, and serialization behavior are described.

  • User schemas

  • UserUpdate: Partial updates for user profile fields with optional fields for email, name, telegram_id, and is_active.

  • UserResponse: Complete user representation including identifiers, contact info, activity flag, and timestamps. Uses attribute-based serialization.

  • Course schemas

  • CourseResponse: Course metadata including code, title, URL, instructor, institute, and NC code, plus creation/update timestamps. Uses attribute-based serialization.

  • Announcement schemas

  • AnnouncementResponse: Announcement details linked to a course, including title, ISO date string, content, and fetch timestamp. Uses attribute-based serialization.

  • Subscription schemas

  • SubscriptionCreate: Minimal input to subscribe to a course by course code.

  • SubscriptionResponse: Subscription record with foreign keys, activation flag, and timestamps. Uses attribute-based serialization.

  • Notification schemas

  • NotificationResponse: Notification record with foreign keys to user, subscription, and announcement, optional channel reference, sent timestamp, and read flag. Uses attribute-based serialization.

  • Notification Channel schemas

  • NotificationChannelCreate: Input to create a channel with channel type, address, and optional activation flag.

  • NotificationChannelResponse: Full channel record with foreign key, channel type, address, activation flag, and timestamps. Uses attribute-based serialization.

  • Authentication schemas

  • OtpRequest: Request to initiate OTP for an email.

  • OtpVerify: Request to verify OTP with email and code.

  • AuthStatus: Response indicating authenticated user and whether the user was newly registered.

  • OtpRequestResponse: Confirmation of OTP initiation with message, new user flag, and expiration timestamp.

Validation rules and behaviors:

  • Email fields use validated email types.
  • Optional fields are union types with None where applicable.
  • Attribute-based serialization is enabled via model configuration, aligning schema fields with ORM attributes.
  • Unique constraints and indexes are defined in the database models (e.g., unique email, unique telegram_id, unique course code, unique channel+address per user).

Architecture overview#

The API follows a layered architecture:

  • Routers expose endpoints and delegate to services.
  • Schemas define request/response contracts and enable automatic validation and serialization.
  • Services orchestrate business logic and interact with repositories backed by Tortoise ORM models.
  • Models define database tables, relationships, and constraints.

Detailed component analysis#

User operations#

  • Schema: UserUpdate and UserResponse
  • Validation rules
  • Optional fields allow partial updates.
  • Email is validated; other fields are string-based.
  • Serialization/deserialization
  • Attribute-based serialization enabled; schema fields mirror ORM attributes.
  • Example payloads
  • Request (partial update): {“email”: “[email protected]”, “name”: “Updated Name”}
  • Response: {“id”: 1, “email”: “[email protected]”, “name”: “John Doe”, “telegram_id”: “tg123”, “is_active”: true, “created_at”: “…”, “updated_at”: “…”}

Course management#

  • Schema: CourseResponse
  • Validation rules
  • String fields with length constraints reflected in ORM.
  • Serialization/deserialization
  • Attribute-based serialization enabled; schema fields mirror ORM attributes.
  • Example payload
  • Response: {“id”: 1, “code”: “CS101”, “title”: “Intro to CS”, “url”: “https://example.com/cs101”, “instructor”: “Dr. Smith”, “institute”: “Example U”, “nc_code”: “NC123”, “created_at”: “…”, “updated_at”: “…”}

Announcement retrieval and filtering#

  • Schema: AnnouncementResponse
  • Validation rules
  • Date stored as string; content as text; fetch timestamp auto-generated.
  • Serialization/deserialization
  • Attribute-based serialization enabled; schema fields mirror ORM attributes.
  • Example payload
  • Response: {“id”: 1, “course_id”: 1, “title”: “Quiz Announced”, “date”: “2025-04-01”, “content”: “Details…”, “fetched_at”: “…”}

Subscription CRUD operations#

  • Schemas: SubscriptionCreate and SubscriptionResponse
  • Validation rules
  • SubscriptionCreate requires course code; SubscriptionResponse includes activation flag and timestamps.
  • Serialization/deserialization
  • Attribute-based serialization enabled; schema fields mirror ORM attributes.
  • Example payloads
  • Request: {“course_code”: “CS101”}
  • Response: {“id”: 1, “user_id”: 1, “course_id”: 1, “is_active”: true, “created_at”: “…”}

Notification delivery and status tracking#

  • Schemas: NotificationResponse and NotificationChannel schemas
  • Validation rules
  • NotificationResponse includes optional channel reference; channel address and channel type constrained by model.
  • Serialization/deserialization
  • Attribute-based serialization enabled; schema fields mirror ORM attributes.
  • Example payloads
  • Notification response: {“id”: 1, “user_id”: 1, “subscription_id”: 1, “announcement_id”: 1, “channel_id”: 1, “sent_at”: “…”, “is_read”: false}
  • Channel create: {“channel”: “email”, “address”: “[email protected]”, “is_active”: true}
  • Channel response: {“id”: 1, “user_id”: 1, “channel”: “email”, “address”: “[email protected]”, “is_active”: true, “created_at”: “…”}

Authentication flows#

  • Schemas: OtpRequest, OtpVerify, AuthStatus, OtpRequestResponse
  • Validation rules
  • Email fields are validated; OTP code is a string.
  • Example payloads
  • OTP request: {“email”: “[email protected]”}
  • OTP verify: {“email”: “[email protected]”, “code”: “123456”}
  • OTP request response: {“message”: “OTP sent”, “is_new_user”: false, “expires_at”: “…”}
  • Auth status: {“user”: {…UserResponse…}, “is_new_user”: false}

Dependency analysis#

The schemas depend on Pydantic for validation and serialization. They are consumed by routers and services, and mapped onto Tortoise ORM models for persistence. The application factory wires routers into the FastAPI app.

Performance considerations#

  • Attribute-based serialization reduces mapping overhead by aligning schema fields with ORM attributes.
  • Unique constraints in models minimize duplicate writes and improve lookup performance.
  • Consider pagination for listing endpoints (courses, announcements, notifications) to limit payload sizes.
  • Use selective field projection in queries to avoid loading unnecessary data.

Troubleshooting guide#

Common validation errors and their likely causes:

  • Email validation failures: Ensure the email field matches the validated email type.
  • Missing required fields: SubscriptionCreate requires course_code; Auth requests require email and code where applicable.
  • Type mismatches: Confirm numeric fields (IDs, booleans) match expected types.

Operational checks:

  • Verify attribute-based serialization is enabled in schemas to prevent missing fields during ORM mapping.
  • Confirm unique constraints are respected to avoid duplicate entries.

Conclusion#

Pydantic at the edge, Tortoise inside. Optional fields on update schemas are intentional; do not require them on PATCH-like flows.

Appendices#

Relationship between database models and API schemas#

  • User: UserResponse mirrors User model fields; attribute-based serialization enables smooth conversion.
  • Course: CourseResponse mirrors Course model fields; attribute-based serialization enables smooth conversion.
  • Announcement: AnnouncementResponse mirrors Announcement model fields; attribute-based serialization enables smooth conversion.
  • Subscription: SubscriptionResponse mirrors Subscription model fields; attribute-based serialization enables smooth conversion.
  • Notification: NotificationResponse mirrors Notification model fields; attribute-based serialization enables smooth conversion.
  • NotificationChannel: NotificationChannelResponse mirrors NotificationChannel model fields; attribute-based serialization enables smooth conversion.

Data transformation patterns#

  • Schemas act as adapters between external clients and internal ORM models.
  • Attribute-based serialization eliminates manual field mapping in most cases.
  • Services receive validated models and convert them to ORM instances for persistence.

API versioning strategies#

  • Current project version: 0.1.0
  • Recommendation: Introduce a version prefix in route paths (e.g., /api/v1/) and maintain backward compatibility by deprecating older endpoints rather than removing them immediately. This allows clients to migrate gradually.